<html>
<head>
<title>Microstation DGN Feature Representation</title>
</head>
<body bgcolor="#ffffff">

<h1>Microstation DGN Feature Representation</h1>

This document addresses how DGN features should be drawn to match the
behavior of Microstation as closely as possible.  It is written for
users of the <a href="index.html">dgnlib</a> reader code, but the information
should be applicable to anyone working with DGN.<p>

The information is based on the ISFF.TXT document, supposition, and
review of display effects in various viewers.  It is incomplete, and at times
likely incorrect.  I would appreciate feedback at
<a href="mailto:warmerdam@pobox.com">warmerdam@pobox.com</a>.<p>

<h2>General Symbology Information</h2>

All graphical elements contain a set of common information, represented by
the following fields in DGNElemCore.<p>

<ol>
<li> <b>int color</b>
<li> <b>int weight</b>
<li> <b>int style</b>
<li> <b>int properties</b>
</ol>

<h3>Color</h3>

The color field of the DGNElemCore is a color index number (0-255),
referencing a color from the appropriate color table.  This is normally
translated into an
RGB color for use using DGNLookupColor().  The returned color should be
considered the foreground color for drawing the element.<p>

<i>NOTE: There can be more than one color table in a DGN file, and
currently on the first is utilized.  In theory the screen or view value from
the colormap should be used to establish which is to be used but this doesn't
seem to be an issue in any sample data I have encountered.</i><p>

<h3>Weight</h3>

This is a value between 0 and 31 which is supposed to establish the weight, or
thickness of lines for this element.  It is unclear how this should be
utilized.  Geographic Explorer treats it as a line width in pixels.<p>

<h3>Style</h3>

The style field has one of the following values, with 0 (Solid) being
the default.  Presumably this only affects drawing of line segments.  There
is no information on appropriate sizing information for dashes or dots, or
relative guidelines implicit in the names.<p>

<ul>
<li> DGNS_SOLID (0)
<li> DGNS_DOTTED (1)
<li> DGNS_MEDIUM_DASH (2)
<li> DGNS_LONG_DASH (3)
<li> DGNS_DOT_DASH (4)
<li> DGNS_SHORT_DASH (5)
<li> DGNS_DASH_DOUBLE_DOT (6)
<li> DGNS_LONG_DASH_SHORT_DASH (7)
</ul>

<h3>Properties</h3>

The properties bitfield in DGNElemCore contains various possible values, but
only a few affect drawing.<p>

The <b>DGNPF_ORIENTATION</b> flag is set an element is to be oriented relative
to the screen, instead of relative to the design plane.  It isn't clear what
all properties this affects, perhaps the orientation of text in a viewer
that can rotate the view of the file as a whole.  No examples of this being
used have been found.<p>

If used with a line element, the <b>DBNPF_HOLE</b> flag indicates that
the line should be treated as infinite, while it is otherwise just a segment
between the two provided points.  If used with a closed element (shape,
complex shape, ellipse, ...) it indicates that shape is a hole (unfilled) while
by default such elements are filled.<p>

<h2>Element Types</h2>

<h3>DGNT_LINE</h3>

Single line segment.  Use color, weight and line
style.<p>

<h3>DGNT_LINESTRING</h3>

Polyline.  Use color, weight, and line style.<p>

<h3>DGNT_SHAPE</h3>

Polygon.  Use color for edge color.  If the polygon is supposed to be filled
the <a href="dgn.html#ul0x0041">0x0041</a> fill information attribute
linkage will also be included.  The fill color may differ from the element
color in which case the element should be filled with the fill color, and
then the boundary drawn in the element (outline) color.<p>

If the DGNPF_HOLE flag is set the shape is really a hole within another
element and should be "cleared".  The exact semantics are unclear.  The
first and last vertices of a shape are always the same.<p>

<h3>DGNT_CURVE</h3>

The curve (type 11) element is a 2D or 3D parametric spline curve completely defined by a set of n points. The first two and last two points define
endpoint derivatives and do not display. The interpolated curve passes through all other points.<p>

A curve with n points defines n-1 line segments; interpolation occurs over the middle n-5 segments. Each segment has its own parametric cubic
interpolation polynomial for the x and y (and z in 3D) dimensions. The parameter for each of these polynomials is the length along the line segment.
Thus, for a segment k, the interpolated points P are expressed as a function of the distance d along the segment as follows:<p>
<pre>
       Pk(d) = {Fk,x(d), Fk,y(d), Fk,z(d)} with 0 <= d <= Dk
</pre>

Fk,x, Fk,y, and Fk,z are cubic polynomials and Dk is the length of segment k.
In addition, the polynomial coefficients are functions of the segment
length and the endpoint derivatives of Fk,x, Fk,y, and Fk,z. The subscript k
is merely a reminder that these functions depend on the segment.<p>

The cubic polynomials are defined as follows:<p>
<pre>
    Fk,x = axd3 + bxd2 + cxd + Xk
    cx = tk
    bx = [3(Xk+1-Xk)/Dk - 2tk,x - tk+1,x] / Dk
    ax = [tk,x + tk+1,x - 2(xk+1-xk)/Dk] / Dk2
</pre>
The m variable is analogous to the slope of the segment.<p>

<pre>
 If (|mk+1,x-mk,x| + |mk-1,x-mk-2,x|) <> 0, then:
    tk,x = (mk-1,x|mk+1,x-mk,x| + mk,x|mk-1,x-mk-2,x|)/(|mk+1,x-mk,x| +
    |mk-1,x-mk-2,x|)
 else:
    tk,x = (mk+1,x+mk,x) / 2
    mk,x = (Xk+1 - Xk) / Dk
</pre>
Fk,y(d) and Fk,z(d) are defined analogously.<p>

<h3>DGNT_BSPLINE</h3>

<i>Fill in later.</i>

<h3>DGNT_ELLIPSE</h3>

Ellipse.  See DGNT_ARC for details of geometry.  The DGNPF_HOLE and
fill color information are applied to ellipses in the same manner as
they are applied to the Shape. <p>

<h3>DGNT_ARC</h3>

Arc (portion of ellipse). Draw line with color, line style and weight.<p>

The DGNElemArc (also used for ellipses) looks like this:
<pre>
typedef struct {
  DGNElemCore 	core;
  DGNPoint	origin;
  double	primary_axis;
  double        secondary_axis;
  double	rotation;
  long          quat[4];
  double	startang;
  double	sweepang;
} DGNElemArc;
</pre>

The origin is the center of rotation for the ellipse or arc.<P>

The primary_axis and secondary_axis define the distance from the origin to
the ellipse edge on the primary (horizontal) and secondary (vertical) axis.<P>

The rotation indicates the counterclockwise (or clockwise if negative)
rotation in degrees of the defined ellipse around the origin.  <p>

The startang indicates the start angle (degrees, counterclockwise) of the
arc.  For ellipses this is always 0.<p>

The sweepang indicates the angle through which the arc sweeps (counterclockwise
in degrees, clockwise if negative).  For ellipses this is always 360.<p>

The DGNStrokeArc() function can be used to approximate arcs and ellipses as
a polyline.<p>

<h3>DGNT_TEXT</h3>

Text.  Should be drawn using color.  The text structure looks like:<p>

<pre>
typedef struct {
    DGNElemCore core;

    int		font_id;
    int		justification;
    long        length_mult;
    long        height_mult;
    double	rotation;
    DGNPoint	origin;
    char	string[1];
} DGNElemText;
</pre>

The font_id is a value from 0-255 for the to use.  It is unclear to me at
this time how this can be related to a non-microstation specific font. <p>

The justification is generally ignored, since the provided origin is always
at the bottom left of the text to be placed.  The justification relates to
how the user originally placed the text.<p>

The rotation indicates the rotation in degrees counterclockwise of the
text (zero is horizontal, left to right). <p>

The origin is position where the bottom left corner of the text is placed.<p>

The height_mult field gives the height of the text in master coordinates.
This appears to be the height of a line, measuring distance from the baseline
of one line to the next, and is usually a bit more than the height of the text
itself. <p>

If length_mult is different than height_mult, it means the aspect ratio of
the text has been adjusted from the default.<P>

<h2>Level Symbology</h2>

<i>Fill in later.</i><p>



</BODY>
</html>
